Ik heb een map vol met tekstbestanden. Mijn doel is om tekst toe te voegen aan het begin en einde van allemaal. De tekst die aan het begin en aan het einde komt, is voor elk bestand hetzelfde.
Gebaseerd op de code die ik van internet heb gekregen, is dit de code om aan het begin van het bestand toe te voegen:
echo -e "var language = {\n$(cat $BASEDIR/Translations/Javascript/*.txt)" > $BASEDIR/Translations/Javascript/*.txt
Dit is de code om toe te voegen aan het einde van het bestand. Het doel is om de tekst };
aan het einde van elk bestand toe te voegen:
echo "};" >> $BASEDIR/Translations/Javascript/*.txt
De voorbeelden waaruit ik put waren voor het handelen op individuele bestanden. Ik dacht dat ik “zou proberen te reageren op meerdere bestanden met behulp van het jokerteken, *.txt
.
Ik zou ook andere fouten kunnen maken. Hoe kan ik in elk geval tekst toevoegen aan het begin en einde van meerdere bestanden?
Answer
Om tekst voor een bestand te plaatsen dat u kunt gebruiken (met de GNU-implementatie van sed
):
sed -i "1i some string" file
Tekst toevoegen is net zo eenvoudig als
echo "Some other string" >> file
Het laatste dat u moet doen, is dat in een lus plaatsen die zich herhaalt over alle bestanden die u wilt bewerken:
for file in *.txt; do sed -i "1i Some string" "$file" && echo "Some other string" >> "$file" done
Answer
Je kunt GNU sed gebruiken
Zoals al geïllustreerd, kun je regels tekst invoegen vlak voor en na het matchen regels van een bestand met sed
, met respectievelijk de opdracht i
en a
. Wat heeft “Wat niet is aangetoond, is dat je het kunt doen met een oneliner en voor meerdere bestanden tegelijk.
Het volgende zal een regel invoegen vóór de eerste 1i
en na de laatste regel $a
. De invoegingen worden uitgevoerd voor alle bestanden die overeenkomen met de glob *.txt
.
sed -i -e "1ivar language = {" -e "$a};" -- *.txt
Beide i
en a
werken niet alleen met regelnummers, maar ook op elke regel die overeenkomt met een bepaald patroon. Dit zou een commentaar invoegen wanneer een regel var y = 2;
bevat:
sed -i -- "/var y = 2;/i//initialize variable y" *.js
Antwoord
Volledig POSIX-compatibel commando, gebruikmakend van ex
:
for f in *.txt; do printf "%s\n" 0a "var language = {" . "$a" "};" . x | ex "$f"; done
Als u het printf
-gedeelte van de opdracht zelf uitvoert, ziet u de exacte bewerkingsopdrachten die deze wordt doorgegeven aan ex
:
0a var language = { . $a }; . x
0a
betekent “Toevoegen tekst na regel 0 “(met andere woorden, vóór de eerste regel). De volgende regel is de letterlijke tekst die moet worden “toegevoegd” na regel 0. De punt (.
) op een regel op zichzelf beëindigt de toe te voegen tekst.
$a
betekent tekst toevoegen na de laatste regel van het bestand.
x
betekent de wijzigingen opslaan en afsluiten .
Antwoord
Hier is een manier om het te doen in Perl:
for f in ./*txt; do perl -lpe "BEGIN{print "First string"}END{print "Last string"}" "$f" > foo && mv foo "$f"; done
Reacties
Answer
Heeft ook het recht om te zijn (met resultaten in .out
bestanden):
find . -name "*.txt" -exec sh -c "(echo HEAD;cat {};echo FOOT) > {}.out" \;
Nog een, meer uitgewerkte variant – bronbestanden vervangen door resultaat:
find . -name "*.txt" -exec sh -c "(echo HEAD;cat {};echo FOOT) > {}.tmp && mv {}.tmp {}" \; -print
Antwoord
Probeer ex
:
ex -s +"bufdo!1s/^/HEAD/|$s/$/TAIL/" -cxa *.foo
te gebruiken waar commandos zijn:
-
bufdo!
voert onderstaande opdrachten uit voor elke geopende buffer / bestand (opmerking: het is “niet POSIX ) -
1s/^/HEAD/
– voegtHEAD
tekst in op de eerste regel aan het begin van de regel -
$s/$/TAIL/
– voegtTAIL
tekst toe aan de laatste regel aan het einde van de regel
en argumenten zijn:
-
-s
– stille / snelle modus -
-cxa
– sla alle geopende buffers / bestanden op en sluit af -
*.foo
– alle bestanden in de huidige directory (*
) metfoo
extensie, gebruik**/*.foo
voor recursiviteit (na het inschakelen van globstar:shopt -s globstar
)
Reacties
- opmerking bufdo is niet POSIX pubs.opengroup.org/onlinepubs/9699919799/utilities/ex.html
- @StevenPenny heeft gelijk. Ik gebruik alleen POSIX-gespecificeerde functies persoonlijk voor scriptbewerkingen.
Antwoord
Met gnu awk
, gebruikmakend van de inplace
extensie en BEGINFILE
/ ENDFILE
:
gawk -i inplace "BEGINFILE{print "INSERT"};ENDFILE{print "APPEND"};1" ./*.txt
Antwoord
Perl one-liner schiet te hulp:
perl -i -pe"$_="FIRST LINE\n$_"if$.<2;$.=0,$_.="LAST LINE\n"if eof" *.txt
-i
in plaats van dat deze bestandsvervanging niet werkt, wordt alleen afgedrukt naar stdout.