У меня есть файл f1.txt
:
ID Name
1 a
2 b
3 g
6 f
Количество пробелов не фиксировано. Каков наилучший способ заменить все пробелы одним пробелом, используя только tr
?
Это то, что я до сих пор:
cat f1.txt | tr -d " "
Но вывод:
IDName
1a
2b
3g
6f
Но я хочу, чтобы это выглядело так:
ID Name
1 a
2 b
3 g
6 f
Пожалуйста, попробуйте и избегайте sed
.
sed
. Хотел узнать другие способыОтветы:
С
tr
помощьюs
опции повтора queeze :Или вы можете использовать
awk
решение:Когда вы изменяете поле в записи,
awk
перестраиваете$0
, берете все поля и объединяете их вместе, разделяя ихOFS
, что по умолчанию является пробелом.Это позволит сжать последовательности пробелов и табуляции (и, возможно, других пустых символов в зависимости от локали и реализации
awk
) в один пробел, но также удалит начальные и конечные пробелы с каждой строки.источник
awk
, он может сделать все, что угодно. Вы также можете принять его решение. Только одно: Gnouc, не могли бы вы объяснить, что делает формат awk в вашей команде? Также вы можете добавить табуляции / пробелы, чтобы вывод соответствовал ожидаемому выводу Неизвестного?column -t
делает. Добавить объяснение дляawk
.tr
заменит два пробела в конце строки одним пробелом.awk
удалит все завершающие пробелы.Просто используйте
column
:Выход:
источник
column -t f1.txt | cut -d " " -f2
но это не было решением, которого я ожидалcolumn -t file | awk '{print $2}'
печатает только второй столбецЕсли вы хотите сжать «пробел», вам нужно использовать предопределенные наборы символов tr «: blank:» (горизонтальная табуляция и пробел) или «: space:» (вертикальный пробел):
Примеры были запущены на Red Hat 5 (GNU tr).
В моем случае я хотел нормализовать все пробелы в одном пробеле, чтобы я мог положиться на пространство в качестве разделителя.
Как указано во втором комментарии Дастробу, я пропустил формулировку на странице руководства:
Это позволяет нам исключить первый тр. Кудо Скотту за терпение перед лицом моей глупости.
До этого разбирал порт из конфига Redis. файл:
После, с SET2, указанным с помощью squeeze:
Выход:
Для более подробной информации о нюансах пробелов
Продемонстрируйте, где одно только сжатие не срабатывает, когда задействованы последовательные смешанные символы, попадающие в класс символов [: blank:]:
Примечание: два моих строковых поля в формате printf разделены 1 пробелом, 1 табуляцией, 1 пробелом. После сжатия эта последовательность все еще существует. На выходе октального дампа это представлено последовательностью ascii 040 011 040.
источник
tr "[:blank:]" " " | tr -s "[:blank:]"
? Я думаю, первой части будет достаточно, т. Е.tr "[:blank:]" " "
Поскольку она нормализует пробелы и уже выполняет подстановку. Со страницы руководства: «Сжатие нескольких вхождений символов [...] Это происходит после того, как все удаление и перевод завершены».printf 'ID \t Name\n' | tr -s "[:blank:]" " " | od -cb
(как предложено @dastrobu), и я получилID Name\n
(с одним пробелом) в качестве вывода. Вы действительно пробовали это, @ user3183018?printf 'ID␣\t␣Name\n' | tr -s "[:blank:]" "␣"
(как предложено @dastrobu), где␣
представляет пробел, и я получилID␣Name\n
(с одним пробелом) в качестве вывода. Это точно так же, как ваш пример «Порт <SPACE> <TAB> <SPACE> 6379», за исключением того, что я использовал строки заголовка из вопроса. Мне интересно, пытались ли выtr -s "[:blank:]"
(без окончательного"␣"
аргумента).printf 'ID \t Name\n' | od -cb
, он показывает именно то, что он должен:I
D
\t
N
a
m
e
\n
(т.е.I
D
040
011
040
N
a
m
e
\n
). Между тем, по вашим собственным данным, вы делаете именно ту ошибку, о которой я догадывался: вы выполняетеtr -s "[:blank:]"
(то естьtr
с одним параметром и одним аргументом) вместо команды, которую @dastrobu и я представили четыре раза:tr -s '[:blank:]' '␣'
(т.е.tr
с одним вариантом и двумя аргументами ).Кому нужна программа (кроме оболочки)?
Если вы хотите, чтобы значения во втором столбце выстраивались в линию, как в ответе polym
column
, используйтеprintf
вместоecho
:источник
tr
вызова - что не говоря уже о том, сколько еще работы требуется, чтобы написать. И последнее, разве вы не сказали бы, что этот пост на самом деле не отвечает на заданный вопрос? Каков наилучший способ заменить все пробелы одним пробелом, используя только tr?$IFS
? Может быть , как:IFS=' <tab>' set -f ; echo $(cat <file)
?Это старый вопрос, решаемый много раз. Просто для полноты: у меня была проблема с аналогами, но я хотел передать линии по трубе в другую программу. Я использовал Xargs .
так ,
cat f1.txt | xargs -L1
кажется, выход именно то , что вы хотите.источник