Как обработать текстовый файл с несколькими столбцами, чтобы получить еще один текстовый файл с несколькими столбцами?

comm -1 -3 <( cd dir1 && find -maxdepth 1 -type d | sort ) <( cd dir2 && find -maxdepth 1 -type d | sort ) | ( cd dir2 && xargs rm -rf )

с разрывы строк для удобства чтения:

comm -1 -3 <( cd dir1 && find -maxdepth 1 -type d | sort ) \
           <( cd dir2 && find -maxdepth 1 -type d | sort ) \
                | ( cd dir2 && xargs rm -rf )

объяснение

find -maxdepth 1 -type d

перечисляет только каталоги без подкаталогов.

cd dir1 && find -maxdepth 1 -type d | sort

сначала перейдите в каталог, затем выведите список каталогов.

<( ... )

процесс замещения .

comm -1 -3 <( ... ) <( ... )

принимают первый ввод и второй ввод и выводят строки, уникальные для второго ввода. фактически это будет печатать каталоги, которые находятся в dir2 , но не в dir1 .

... | ( cd dir2 && xargs rm -rf )

измените рабочий каталог на dir2 , затем выполните rm -rf с выводом предыдущей команды в качестве аргументов. фактически это удалит каталоги, которые находятся в dir2 , но не в dir1 .

сначала протестируйте, удалив канал к xargs и проверив вывод.

17
14.09.2016, 04:51
8 ответов

Поместите каждое поле в строка и постколонка.

Каждое поле в одной строке

tr

tr -s ' ' '\n' < infile

grep

grep -o '[[:alnum:]]*' infile

sed

sed 's/\s\+/\n/g' infile

или более переносимых:

sed 's/\s\+/\
/g' infile

awk

awk '$1=$1' OFS='\n' infile

или

awk -v OFS='\n' '$1=$1' infile

Columnate

paste

Для 2 столбцов:

... | paste - -

Для 3 столбцов:

... | paste - - -

и т. Д.

sed

Для 2 столбцов:

... | sed 'N; s/\n/\t/g'

Для 3 столбцов:

... | sed 'N; N; s/\n/\t/g'

и т. Д.

xargs

... | xargs -n number-of-desired-columns

Поскольку xargs использует / bin / echo для печати, помните, что данные, которые выглядят как параметры для echo , будут интерпретироваться как таковые.

awk

... | awk '{ printf "%s", $0 (NR%n==0?ORS:OFS) }' n=number-of-desired-columns OFS='\t'

pr

... | pr -at -number-of-desired-columns

или

... | pr -at -s$'\t' -number-of-desired-columns

столбцы (из пакета autogen)

... | columns -c number-of-desired-columns

Типичный вывод:

a   aa  aaa
b   bb  bbb
c   cc  ccc
d   dd  ddd
e   ee  eee
f   ff  fff
g   gg  ggg
h   hh  hhh
i   ii  iii
j   jj  jjj
20
27.01.2020, 19:46
$ sed -E 's/\s+/\n/g' ip.txt | paste - -
a   aa
aaa b
bb  bbb
c   cc
ccc d
dd  ddd
e   ee
eee f
ff  fff
g   gg
ggg h
hh  hhh
i   ii
iii j
jj  jjj

$ sed -E 's/\s+/\n/g' ip.txt | paste - - -
a   aa  aaa
b   bb  bbb
c   cc  ccc
d   dd  ddd
e   ee  eee
f   ff  fff
g   gg  ggg
h   hh  hhh
i   ii  iii
j   jj  jjj
9
27.01.2020, 19:46

Как указал подстановочный знак, это будет работать только в том случае, если ваш файл правильно отформатирован, в котором нет специальных символов, которые оболочка будет интерпретировать как глобусы, и вы довольны правилами разделения слов по умолчанию. Если есть какие-либо вопросы о том, пройдут ли ваши файлы этот тест, не используйте этот подход.

Одна из возможностей - использовать printf , как

printf '%s\t%s\n' $(cat your_file)

. Это будет выполнять разделение слов в содержимом your_file , объединить их в пары и распечатать с вкладками между ними. . Вы можете использовать больше строк формата % s в printf , чтобы иметь дополнительные столбцы.

9
27.01.2020, 19:46

Вы также можете сделать это с помощью одного вызова GNU awk:

reshape.awk

# Set awk to split input at whitespace characters and
# use tab as the output field separator 
BEGIN {
  RS="[ \t\n]+"
  OFS="\t"
}

# Print using OFS or ORS based on the element index
{
  printf "%s", $1 (NR%n == 0 ? ORS : OFS)
}

# Append a missing new-line when last row is not full
END { 
  if( NR%n != 0) 
    printf "\n"
}

Запустите его так:

awk -f reshape.awk n=2 infile

Или как однострочник:

awk -v n=2 'BEGIN { RS="[ \t\n]+"; OFS="\t" } { printf "%s", $1 (NR%n == 0 ? ORS : OFS) } END { if( NR%n != 0) printf "\n" }' infile

Вывод:

a   aa
aaa b
bb  bbb
c   cc
ccc d
dd  ddd
e   ee
eee f
ff  fff
g   gg
ggg h
hh  hhh
i   ii
iii j
jj  jjj

Или с n = 3 :

a   aa  aaa
b   bb  bbb
c   cc  ccc
d   dd  ddd
e   ee  eee
f   ff  fff
g   gg  ggg
h   hh  hhh
i   ii  iii
j   jj  jjj
1
27.01.2020, 19:46

Подход с использованием сценария Python.

Основная идея здесь состоит в том, чтобы объединить все слова в вашем тексте в один список, а затем печатать новую строку после каждого второго элемента (это для разбивки на две колонки). Если вам нужно 3 столбца, измените index% 2 на index% 3

#!/usr/bin/env python3
import sys

items = [i for l in sys.stdin 
           for i in l.strip().split()]
line = []
for index,item in enumerate(items,1):
    line.append(item)
    if index%2 == 0:
       print("\t".join(line))
       line = []

Пример вывода:

$ python recolumnate.py < input.txt                                            
a   aa
aaa b
bb  bbb
c   cc
ccc d
dd  ddd
e   ee
eee f
ff  fff
g   gg
ggg h
hh  hhh
i   ii
iii j
jj  jjj

Версия с тремя столбцами (как сказано выше, только index% 3 == 0 изменено)

$ cat recolumnate.py                                                           
#!/usr/bin/env python3
import sys

items = [i for l in sys.stdin 
           for i in l.strip().split()]
line = []
for index,item in enumerate(items,1):
    line.append(item)
    if index%3 == 0:
       print("\t".join(line))
       line = []

$ python recolumnate.py < input.txt                                            
a   aa  aaa
b   bb  bbb
c   cc  ccc
d   dd  ddd
e   ee  eee
f   ff  fff
g   gg  ggg
h   hh  hhh
i   ii  iii
j   jj  jjj
3
27.01.2020, 19:46
perl -n0E 'say s/\s+/ ++$n % 4 ?"\t":"\n"/gre' file

(замените 4 на количество столбцов)

4
27.01.2020, 19:46

Утилита BSD rs (изменение формы):

$ rs 0 2
a   aa  aaa     b   bb  bbb     c   cc  ccc
d   dd  ddd     e   ee  eee     f   ff  fff
g   gg  ggg     h   hh  hhh     i   ii  iii
j   jj  jjj
[Ctrl-D][Enter]
a    aa
aaa  b
bb   bbb
c    cc
ccc  d
dd   ddd
e    ee
eee  f
ff   fff
g    gg
ggg  h
hh   hhh
i    ii
iii  j
jj   jjj

0 2 равно строк и столбцы . Указание 0 означает «автоматическое вычисление строк из столбцов».

4
27.01.2020, 19:46

Две колонки

perl -pne "s/ /\n/g" filename| sed '/^$/d'| sed "N;s/\n/ /g"

выход

a aa
aaa b
bb bbb
c cc
ccc d
dd ddd
e ee
eee f
ff fff
g gg
ggg h
hh hhh
i ii
iii j
jj jjj

Три столбца

    perl -pne "s/ /\n/g" filename| sed '/^$/d'| sed "1~3N;s/\n/ /g"| sed "N;s/\n/ /g"

a aa aaa
b bb bbb
c cc ccc
d dd ddd
e ee eee
f ff fff
g gg ggg
h hh hhh
i ii iii
j jj jjj
1
17.10.2021, 16:52

Теги

Похожие вопросы