Ich habe eine Zeichenfolge wie:dog cat bird whale
Und ich möchtedog dog cat cat bird bird whale whale
Alle Wörter stehen in derselben Zeile. Irgendeine Idee?
Antwort1
Ergänzung zur Lösungsfamilie :-) .
duplicator.sh
:
for i; do echo -n "$i $i "; done; echo
Ausführbar machen, und jetzt:
$ ./duplicator.sh dog cat bird whale
dog dog cat cat bird bird whale whale
Alternativ als Shell-Funktion, zB zur Wiederverwendung innerhalb eines Skripts:
duplicator() {
for i; do echo -n "$i $i "; done; echo
}
die dann direkt ausgeführt werden können, wo definiert als
duplicator dog cat bird whale
Antwort2
Du könntest benutzen sed
:
sed -r 's/(\S+)/\1 \1/g' filename
Wenn Sie die Änderungen an der Datei direkt speichern möchten, sagen Sie:
sed -i -r 's/(\S+)/\1 \1/g' filename
Sie könnten auch verwenden perl
:
perl -M5.10.0 -ne 'say join " ", map{$_, $_} split " ";' filename
(Fügen Sie die -i
Option hinzu, die Änderungen direkt an der Datei zu speichern.)
Oder, wie vorgeschlagen vonterdon:
perl -M5.10.0 -ane 'say join " ", map{$_, $_} @F;' filename
Zitat ausperlvar
:
@F
Das Array
@F
enthält die Felder jeder Zeile, die eingelesen werden, wenn der Autosplit-Modus eingeschaltet ist. Informationen zum-a
Schalter finden Sie unter perlrun. Dieses Array ist paketspezifisch und muss deklariert oder mit einem vollständigen Paketnamen versehen werden, wenn es sich bei der Ausführung unter nicht im Paket main befindetstrict 'vars'
.
Antwort3
Was wäre das ohne awk/gawk
Antwort:
$ awk '{ for(i=1;i<=NF+1;i+=1/2) { printf("%s ",$i); }}' <<<"dog cat bird whale"
dog dog cat cat bird bird whale whale
Wenn ein abschließender Zeilenumbruch wichtig ist:
$ awk '{ for(i=1;i<=NF+1;i+=1/2) { printf("%s ",$i); }} END{print ""}' <<<"dog cat bird whale"
Antwort4
Wenn sich Ihr String beispielsweise in einer Variablen befindet, foo="dog cat bird whale"
können Sie Folgendes tun:
Reines Bash:
$ echo "$foo" | (read a b c d && echo "$a $a $b $b $c $c $d $d") dog dog cat cat bird bird whale whale
Erläuterung:Die Klammern sind erforderlich, damit
read
undecho
in derselben Subshell vorkommen und daher Variablen gemeinsam nutzen können. Ohne sieecho
würde nur eine leere Zeile gedruckt.Kernel-Dienstprogramme:
$ join -j 5 -o 1.1,1.1,1.2,1.2,1.3,1.3,1.4,1.4 <(echo $foo) <(echo) dog dog cat cat bird bird whale whale
Erläuterung:Mit dem
-o
Flag vonjoin
können Sie das Ausgabeformat festlegen. Hier sage ich, dass das erste Feld der ersten Datei (1.1
) gedruckt werden soll, gefolgt vom zweiten Feld der ersten Datei (1.2
) usw. Auf diese Weise wird jedes Feld der ersten Datei zweimal gedruckt. ist jedoch sojoin
konzipiert, dass es, nun ja, verbindetzweiEingabezeilen in einem gemeinsamen Feld. Also übergebe ich auch eine leere Zeile (<(echo)
) und ignoriere sie dann. Das-j
legt das Verbindungsfeld fest. Wenn es auf ein nicht vorhandenes (das 5.) gesetzt wird, wirdjoin
die gesamte Zeile gedruckt.Wenn Sie sich nicht um Leerzeichen oder die Eingabereihenfolge kümmern, können Sie Folgendes tun:
$ paste <(echo $foo) <(echo $foo) dog cat bird wale dog cat bird wale
Perl 1:
$ echo $foo | perl -lane 'push @k, $_,$_ for @F; print "@k"' dog dog cat cat bird bird whale whale
Erläuterung:
-l: adds a newline to each print call (among other things) -a: turns on field splitting, fields are saved as @F -n: process input line by line -e: give a script as a command line parameter.
Das obige Skript speichert jedes Feld (von
@F
) zweimal im Array@k
und druckt dann@k
. Wenn Sie den abschließenden Zeilenumbruch nicht benötigen, können Sie ihn vereinfachen zu$ echo $foo | perl -ane 'print " $_ $_" for @F'
Perl 2:
$ echo $foo | perl -0040 -pne 'print "$_"' | paste - - dog dog cat cat bird bird whale whale
Erläuterung:Die
-0
Option setzt das Trennzeichen für den Eingabedatensatz (als Hexadezimal- oder Oktalzahl, sieheHierfür Konvertierungen). Hier stelle ich es auf Oktal ein,040
was ein Leerzeichen ist. Dadurch-p
wirdperl
jede Eingabe „Zeile“ gedruckt und da wir den Datensatztrenner auf Leerzeichen eingestellt haben, werden Zeilen jetzt durch Leerzeichen definiert, sodass jedes Feld zweimal gedruckt wird.awk
:$ echo $foo | awk '{for(i=1;i<=NF;i++){$i=$i" "$i;} 1;}' dog dog cat cat bird bird whale whale
Erläuterung:
NF
ist die Anzahl der Felder, daher geht das obige Skript jedes Feld durch und hängt es an sich selbst an. Sobald dies erledigt ist, drucken wir die Zeile (1;
ist nur eine Abkürzung für Drucken).