Ho alcuni file di testo che contengono alcune colonne separate da un numero diverso di spazi, ma invece ho bisogno di una singola scheda come separatore. È possibile fare in Bash?
Ho alcuni file di testo che contengono alcune colonne separate da un numero diverso di spazi, ma invece ho bisogno di una singola scheda come separatore. È possibile fare in Bash?
Risposte:
Per convertire sequenze di più di uno spazio in una scheda, ma lascia da soli i singoli spazi :
sed 's/ \+ /\t/g' inputfile > outputfile
Per fare questo per un numero di file:
for inputfile in *
do
sed 's/ \+ /\t/g' "$inputfile" > tmpfile && mv tmpfile "$inputfile"
done
o
for inputfile in *
do
sed -i.bak 's/ \+ /\t/g' "$inputfile"
done
o
find . -type f -exec sed -i.bak 's/ \+ /\t/g' {} \;
sed: -e expression #1, char 1: unknown command: `.'
find
uno sul fondo.
sed
non piace avere uno spazio prima dell'estensione di backup. Ho modificato la mia risposta. Grazie per la segnalazione.
Se il tuo personaggio è composto da più schede puoi anche usare tr -s
:
-s, --squeeze-repeats replace each input sequence of a repeated character
that is listed in SET1 with a single occurrence
Per esempio:
my_file.txt | tr -s " "
Tutti gli spazi bianchi diventeranno uno.
È possibile utilizzare sed
per sostituire un numero di spazi con una scheda .:
Esempio per sostituire uno o più spazi con una scheda:
cat spaced-file | sed 's/ \+/\t/g' > tabbed-file
La risposta più semplice usando solo bash
è:
while read -r col1 col2 col3 ...; do
echo -e "$col1\t$col2\t$col3..."
done <file
Se esiste un numero variabile di colonne, puoi farlo, ma funzionerà solo in bash
, non sh
:
while read -r -a cols; do
(
IFS=$'\t'
echo "${cols[*]}"
)
done <file
per esempio
while read -r -a cols; do
(
IFS=$'\t'
echo "${cols[*]}"
)
done <<EOF
a b c
d e f
g h i
EOF
produce:
a b c
d e f
g h i
(c'è una scheda tra ciascuna, ma è difficile vedere quando la incollo qui)
Puoi anche farlo usando sed
o tr
, ma nota che la gestione degli spazi vuoti all'inizio produce risultati diversi.
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
Questa è una soluzione molto semplice:
sed -E 's/\s+/\t/g' your_file > new_file
sed funziona sostanzialmente in questo modo (sed 's / old_pattern / new_pattern / g'). In questo caso il vecchio schema è "\ s +" che significa trovare spazio "s" una o più volte "+" e la barra "\" per interpretarlo come espressione regolare.
Il nuovo modello è la scheda "\ t" che è scritta in formato di espressione regolare e la "g" applica la sostituzione a tutte le righe "a livello globale".