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: `.'
findna dole.
sednie 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ć, sedaby 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 bashnie 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ą sedlub 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”.