У меня есть несколько текстовых файлов, которые содержат несколько столбцов, разделенных различным количеством пробелов, но вместо этого мне нужна одна вкладка в качестве разделителя. Можно ли это сделать в Bash?
У меня есть несколько текстовых файлов, которые содержат несколько столбцов, разделенных различным количеством пробелов, но вместо этого мне нужна одна вкладка в качестве разделителя. Можно ли это сделать в Bash?
Ответы:
Чтобы преобразовать последовательности из более чем одного пробела в табуляцию, но оставить отдельные пробелы в покое :
sed 's/ \+ /\t/g' inputfile > outputfile
Чтобы сделать это для нескольких файлов:
for inputfile in *
do
sed 's/ \+ /\t/g' "$inputfile" > tmpfile && mv tmpfile "$inputfile"
done
или
for inputfile in *
do
sed -i.bak 's/ \+ /\t/g' "$inputfile"
done
или
find . -type f -exec sed -i.bak 's/ \+ /\t/g' {} \;
sed: -e expression #1, char 1: unknown command: `.'
find
что внизу.
sed
не любит иметь пробел перед расширением резервной копии. Я отредактировал свой ответ. Спасибо за отчет.
Если у вашего персонажа несколько вкладок, вы также можете использовать tr -s
:
-s, --squeeze-repeats replace each input sequence of a repeated character
that is listed in SET1 with a single occurrence
Например:
my_file.txt | tr -s " "
Все пробелы станут одним.
Вы можете использовать sed
для замены нескольких пробелов на вкладку .:
Пример замены одного или нескольких пробелов одной вкладкой:
cat spaced-file | sed 's/ \+/\t/g' > tabbed-file
Самый простой ответ, используя только bash
:
while read -r col1 col2 col3 ...; do
echo -e "$col1\t$col2\t$col3..."
done <file
Если есть переменное число столбцов, вы можете сделать это, но он будет работать только в bash
, а не sh
:
while read -r -a cols; do
(
IFS=$'\t'
echo "${cols[*]}"
)
done <file
например
while read -r -a cols; do
(
IFS=$'\t'
echo "${cols[*]}"
)
done <<EOF
a b c
d e f
g h i
EOF
производит:
a b c
d e f
g h i
(между ними есть вкладка, но ее трудно увидеть, когда я ее вставляю)
Вы также можете сделать это с помощью sed
или tr
, но обратите внимание, что обработка пробелов в начале дает разные результаты.
СЭД:
$ sed 's/ */\t/g' << EOF
a b c
d e f
g h i
EOF
a b c
d e f
g h i
Tr:
$ tr -s ' ' '\t' <<EOF
a b c
d e f
g h i
EOF
a b c
d e f
g h i
perl -p -i -e 's/\s+/\t/g' *.txt
Это очень простое решение:
sed -E 's/\s+/\t/g' your_file > new_file
sed в основном работает таким образом (sed 's / old_pattern / new_pattern / g'). В этом случае старый шаблон - «\ s +», что означает поиск пробела «s» один или несколько раз «+» и обратный слеш «\» для интерпретации этого как регулярного выражения.
Новый шаблон - это вкладка «\ t», которая написана в формате регулярных выражений, а «g» применяется для замены всех строк «глобально».