Получение строк полей из файла с разделителями труб

Мне нужно получить первые 9 слов из файла с разделителями каналов, а затем следующие 9 слов. Любая помощь приветствуется.

cat a.txt
a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z|

cat new.ksh
#! /bin/ksh
a=`awk -F "|" ' { print NF-1 } ' a.txt`
echo $a

Expected Output:
a|b|c|d|e|f|g|h|i|
j|k|l|m|n|o|p|q|r|
s|t|u|v|w|x|y|z

Всего 3 ответа


sed -r 's/([^|]*|){9}/&
/g' a.txt

Объяснение: [^|] Не |.
[^|]*| Одно поле (без | ), за которым следует | ,
([^|]*|){9} 9 полей, за которыми следуют | ,
& Заменить с помощью строки, соответствующей новой строке.


Попробуй это:

mayankp@mayank:~/$ cat a.txt| tr "|" "
" |head -9 | tr "
" "|" > output.txt
mayankp@mayank:~/$ echo  >> output.txt
mayankp@mayank:~/$ cat a.txt| tr "|" "
" | tail -18|head -9| tr "
" "|" >> output.txt
mayankp@mayank:~/$ echo  >> output.txt
mayankp@mayank:~/$ cat a.txt| tr "|" "
" | tail -9 | tr "
" "|" >> output.txt
mayankp@mayank:~/$ echo  >> output.txt
mayankp@mayank:~/$ cat output.txt 
a|b|c|d|e|f|g|h|i|
j|k|l|m|n|o|p|q|r|
s|t|u|v|w|x|y|z||

Я чистая версия ksh :

IFS='|'
typeset -a str=( $( < a.txt ) )
len=${#str[@]}
bar='|'
for ((ii=0; ii<len; ii+=9))
do
    max=9
    (( ii+9 > len )) && max=$(( len-ii ))
    for ((jj=0; jj<max; jj++))
    do
        element=$(( ii+jj ))
        (( element == len-1 )) && bar=''
        echo -e "${str[$element]}${bar}c"
    done
    echo
done

Объяснение:

  • IFS : это внутренний разделитель полей, обычно это пробел и табуляция, но если он переназначен, он разделяет другие типы данных.
  • typeset -a Мы создаем массив для хранения данных.
  • str=( $( < a.txt ) ) Мы читаем данные из массива a.txt как элементы массива.
  • len=${#str[@]} Нам нужно знать, как долго массив будет таким, чтобы мы знали, сколько нужно распечатать.
  • Outer for loop, вы хотели видеть значения в группах по 9. Это шаг через массив девять за раз.
  • Чтобы избежать завершения конца, я создал переменную max, которая будет содержать количество элементов в текущей строке. Мы предполагаем, что 9, а затем обновили его, если это необходимо.
  • (( ii+9 > len )) && max=$(( len-ii )) Это делает целочисленное сравнение ii + 9 с длиной. Если условие истинно, мы обновляем max с более низким значением.
  • Внутренний для цикла, это, где мы проходим через элементы линии.
  • element=... Нам нужен элемент ii + jj, поэтому здесь мы вычисляем значение.
  • (( element == len-1 )) && bar='' У вас не было бара в конце. Чтобы избежать печати панели, мы используем переменную bar, и мы ничего не делаем, когда это делается.
  • echo -e "${str[$element]}${bar}c" Здесь мы печатаем этот элемент вместе с переменной столбца. C говорит, что не заканчивайте печать с помощью новой строки. -E требуется, чтобы заставить c работать.
  • echo Так как мы не получали строки для каждого элемента, нам нужно выставить это сейчас, когда у нас есть 9 элементов.

Эта версия также работает с bash.


Есть идеи?

10000