Mam kilka plików tekstowych, które zawierają niektóre kolumny oddzielone różną liczbą spacji, ale zamiast tego potrzebuję jednej pojedynczej karty jako separatora. Czy można to zrobić w Bash?
Mam kilka plików tekstowych, które zawierają niektóre kolumny oddzielone różną liczbą spacji, ale zamiast tego potrzebuję jednej pojedynczej karty jako separatora. Czy można to zrobić w Bash?
Odpowiedzi:
Aby przekonwertować sekwencje więcej niż jednej spacji na tabulację, ale pozostaw pojedyncze spacje w spokoju :
sed 's/ \+ /\t/g' inputfile > outputfile
Aby to zrobić dla wielu plików:
for inputfile in *
do
sed 's/ \+ /\t/g' "$inputfile" > tmpfile && mv tmpfile "$inputfile"
done
lub
for inputfile in *
do
sed -i.bak 's/ \+ /\t/g' "$inputfile"
done
lub
find . -type f -exec sed -i.bak 's/ \+ /\t/g' {} \;
sed: -e expression #1, char 1: unknown command: `.'
find
na dole.
sed
nie lubi mieć spacji przed rozszerzeniem kopii zapasowej. Zredagowałem swoją odpowiedź. Dziękuję za raport.
Jeśli twoja postać ma wiele kart, możesz także użyć tr -s
:
-s, --squeeze-repeats replace each input sequence of a repeated character
that is listed in SET1 with a single occurrence
Na przykład:
my_file.txt | tr -s " "
Wszystkie białe spacje staną się jednym.
Możesz użyć, sed
aby zastąpić wiele spacji tabulatorem:
Przykład zamiany jednego lub więcej spacji na jedną kartę:
cat spaced-file | sed 's/ \+/\t/g' > tabbed-file
Najłatwiejsza odpowiedź, używając tylko bash
:
while read -r col1 col2 col3 ...; do
echo -e "$col1\t$col2\t$col3..."
done <file
Jeśli istnieje zmienna liczba kolumn, można to zrobić, ale to będzie działać tylko na bash
nie sh
:
while read -r -a cols; do
(
IFS=$'\t'
echo "${cols[*]}"
)
done <file
na przykład
while read -r -a cols; do
(
IFS=$'\t'
echo "${cols[*]}"
)
done <<EOF
a b c
d e f
g h i
EOF
produkuje:
a b c
d e f
g h i
(między nimi jest zakładka, ale trudno ją zobaczyć, kiedy ją tu wkleję)
Możesz to również zrobić za pomocą sed
lub tr
, ale zauważ, że obsługa pustych miejsc na początku daje różne wyniki.
sed:
$ 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
To bardzo proste rozwiązanie:
sed -E 's/\s+/\t/g' your_file > new_file
sed zasadniczo działa w ten sposób (sed 's / old_pattern / new_pattern / g'). W tym przypadku stary wzorzec to „\ s +”, co oznacza znalezienie spacji raz lub więcej razy „+” i ukośnik odwrotny „\”, aby zinterpretować to jako wyrażenie regularne.
Nowym wzorcem jest tab „\ t”, który jest zapisany w formacie wyrażeń regularnych, a „g” oznacza zastąpienie wszystkich wierszy „globalnie”.