Принудительный порядок полей вывода из команды вырезания

Я хочу сделать что-то вроде этого:

cat abcd.txt | cut -f 2,1 

и я хочу, чтобы порядок был 2, а затем 1 на выходе. На машине, которую я тестирую (FreeBSD 6), этого не происходит (она печатается в порядке 1,2). Можете ли вы сказать мне, как это сделать?

Я знаю, что всегда могу написать сценарий оболочки для этого реверсирования, но я ищу что-то, используя параметры команды «вырезать».

Я думаю, что использую версию 5.2.1 coreutils, содержащую cut.


person Shreeni    schedule 24.06.2009    source источник


Ответы (2)


Это невозможно сделать с помощью cut. Согласно справочной странице:

Выбранный ввод записывается в том же порядке, в котором он читается, и записывается ровно один раз.

Исправление cut было предложено много раз, но даже полные исправления были отклонены.

Вместо этого вы можете сделать это с помощью awk, например:

awk '{print($2,"\t",$1)}' abcd.txt

Замените \t тем, что вы используете в качестве разделителя полей.

person Lars Haugseth    schedule 24.06.2009
comment
Люди могут прийти сюда в замешательстве, потому что это (неправильное) поведение не задокументировано на cut справочной странице *BSD/macOS. Страница руководства ссылается на стандарт POSIX.2, который действительно определяет порядок вывода. - person internetdotcom; 25.09.2019

Ответ Ларса был отличным, но я нашел еще лучший. Проблема с ним в том, что он соответствует \t\t без столбцов. Чтобы исправить это, используйте следующее:

awk -v OFS="  " -F"\t" '{print $2, $1}' abcd.txt

Где:

-F"\t" — это то, что нужно вырезать точно (вкладки).

-v OFS=" " это то, чем нужно отделяться (два пробела)

Пример:

echo 'A\tB\t\tD' | awk -v OFS="    " -F"\t" '{print $2, $4, $1, $3}'

Это выводит:

B    D    A    
person Evan Moran    schedule 14.09.2012
comment
В Cygwin мне пришлось заменить -F\t на -F\t, чтобы это заработало. - person Panos Rontogiannis; 18.07.2013