Jeg har en katalog full av tekstfiler. Målet mitt er å legge til tekst til begynnelsen og slutten av dem alle. Teksten som går i begynnelsen og slutten er den samme for hver fil.
Basert på koden jeg fikk fra nettet, er dette koden for å legge til i begynnelsen av filen:
echo -e "var language = {\n$(cat $BASEDIR/Translations/Javascript/*.txt)" > $BASEDIR/Translations/Javascript/*.txt
Dette er koden for å legge til i slutten av filen. Målet er å legge til teksten };
på slutten av hver fil:
echo "};" >> $BASEDIR/Translations/Javascript/*.txt
Eksemplene jeg tegnet fra var for å handle på individuelle filer. Jeg trodde jeg skulle prøve å handle på flere filer ved hjelp av jokertegnet, *.txt
.
Jeg kan også gjøre andre feil. I alle fall, hvordan gjør jeg legge til tekst i begynnelsen og slutten av flere filer?
Svar
For å legge tekst til en fil som du kan bruke (med GNU-implementering av sed
):
sed -i "1i some string" file
Tilføying av tekst er så enkel som
echo "Some other string" >> file
Den siste tingen å gjøre er å sette det i en løkke som gjentas over alle filene du har tenkt å redigere:
for file in *.txt; do sed -i "1i Some string" "$file" && echo "Some other string" >> "$file" done
Svar
Du kan bruke GNU sed
Som allerede illustrert, kan du sette inn tekstlinjer rett før og etter samsvar linjer i en fil med sed
, ved å bruke henholdsvis i
og a
. «t er vist er at du kan gjøre det med en en-liner og for flere filer samtidig.
Følgende setter inn en linje før den første 1i
og etter den siste linjen $a
. Innsettingen vil bli utført for alle filer som samsvarer med globen *.txt
.
sed -i -e "1ivar language = {" -e "$a};" -- *.txt
Begge i
og a
fungerer ikke bare med linjenumre, men også på hver linje som samsvarer med et gitt mønster. Dette vil sette inn en kommentar når en linje inneholder var y = 2;
:
sed -i -- "/var y = 2;/i//initialize variable y" *.js
Svar
Fullstendig POSIX-kompatibel kommando ved å bruke ex
:
for f in *.txt; do printf "%s\n" 0a "var language = {" . "$a" "};" . x | ex "$f"; done
Hvis du kjører printf
delen av kommandoen i seg selv, vil du se de nøyaktige redigeringskommandoer som den går til ex
:
0a var language = { . $a }; . x
0a
betyr «Legg til tekst etter linje 0 «(med andre ord før første linje). Neste linje er den bokstavelige teksten som skal «legges til» etter linje 0. Perioden (.
) på en linje i seg selv slutter teksten som skal legges til.
$a
betyr å legge til tekst etter den siste linjen i filen.
x
betyr å lagre endringene og avslutte .
Svar
Her «er en måte å gjøre det i Perl:
for f in ./*txt; do perl -lpe "BEGIN{print "First string"}END{print "Last string"}" "$f" > foo && mv foo "$f"; done
Kommentarer
Svar
Har også rett til å være (med resultater i .out
filer):
find . -name "*.txt" -exec sh -c "(echo HEAD;cat {};echo FOOT) > {}.out" \;
En annen, mer utdypet variant – kildefiler erstattet med resultat:
find . -name "*.txt" -exec sh -c "(echo HEAD;cat {};echo FOOT) > {}.tmp && mv {}.tmp {}" \; -print
Svar
Prøv å bruke ex
:
ex -s +"bufdo!1s/^/HEAD/|$s/$/TAIL/" -cxa *.foo
der kommandoene er:
-
bufdo!
utfører kommandoer nedenfor for hver åpnet buffer / fil (merk: det er ikke POSIX ) -
1s/^/HEAD/
– setter innHEAD
tekst i første linje i begynnelsen av linjen -
$s/$/TAIL/
– legger tilTAIL
tekst på den siste linjen på slutten av linjen
og argumenter er:
-
-s
– stille / rask modus -
-cxa
– lagre alle åpnede buffere / filer og avslutt -
*.foo
– alle filer i den nåværende katalogen (*
) medfoo
utvidelse, bruk**/*.foo
for rekursivitet (etter aktivering av globstar:shopt -s globstar
)
Kommentarer
- merk bufdo er ikke POSIX pubs.opengroup.org/onlinepubs/9699919799/utilities/ex.html
- @StevenPenny har rett. Jeg bruker bare POSIX-spesifiserte funksjoner, personlig, for skriptredigeringer.
Svar
Med gnu awk
, ved hjelp av inplace
utvidelse og BEGINFILE
/ ENDFILE
:
gawk -i inplace "BEGINFILE{print "INSERT"};ENDFILE{print "APPEND"};1" ./*.txt
Svar
Perl one-liner to the rescue:
perl -i -pe"$_="FIRST LINE\n$_"if$.<2;$.=0,$_.="LAST LINE\n"if eof" *.txt
-i
i stedet for denne filutskiftningen fungerer ikke , den skrives bare ut til stdout.