Gebruik een shellactie in Opdrachten om een bewerkte kopie te maken, deze te controleren en de kopie vervolgens in Finder een andere naam te geven. Zo voeg je tekst in op een specifieke regel in een bestaand tekstbestand op de Mac. In deze handleiding voegen we met een tijdelijk voorbeeld één regel in vóór regel 3.

Het doel is een regel toe te voegen aan een klein, lokaal tekstbestand zonder de volgorde van de omliggende regels te veranderen. Je maakt een Finder-opdracht aan die precies één bestand accepteert. De in te voegen tekst en het regelnummer staan in het script, zodat je dezelfde bewerking eenvoudig kunt herhalen op tijdelijke kopieën.

Wat betekent ‘invoegen op regel 3’?

In dit artikel betekent invoegen dat je nieuwe tekst vóór de bestaande genummerde regel plaatst. Als het oorspronkelijke bestand drie regels bevat, resulteert het invoegen van Birch vóór regel 3 in vier regels:

Positie Oorspronkelijk bestand Bewerkt bestand
1 Cedar Cedar
2 Maple Maple
3 Willow Birch
4 — Willow

Een regel is een door een newline afgebakend gegeven, niet een rij die ontstaat doordat tekst in een editor visueel wordt afgebroken. Lege regels tellen mee. Het voorbeeld gebruikt gewone UTF-8-tekst met LF-regeleinden en een newline na de laatste regel. Houd je voor deze oefening aan die voorwaarden; voor rich-textdocumenten en bestanden met andere coderingen of regeleinden is een andere aanpak nodig.

De opdracht die de bewerking uitvoert is macOS sed. De numerieke adressen ervan tellen regels vanaf 1, en de opdracht i schrijft invoegtekst vóór de opgegeven regel. Normaal gesproken schrijft de opdracht de getransformeerde inhoud naar de standaarduitvoer. Dankzij dat gedocumenteerde gedrag kan de opdracht een apart resultaatbestand maken. Apple’s gedistribueerde handleiding voor sed

Een tijdelijk tekstbestand maken

Open Terminal en plak dit volledige installatieblok. Het maakt een map met de naam Line Insert Demo op je bureaublad en een bestand met drie regels, genaamd notes.txt. Als die mapnaam al bestaat, wordt de installatie afgebroken; kies een nieuwe mapnaam voordat je het opnieuw probeert.

/bin/sh <<'SH'
set -e
demo_dir="$HOME/Desktop/Line Insert Demo"
/bin/mkdir "$demo_dir"
printf '%s\n' 'Cedar' 'Maple' 'Willow' > "$demo_dir/notes.txt"
printf 'Created: %s\n' "$demo_dir/notes.txt"
SH

Bij het aanmaken van de map wordt bewust de optie weggelaten waarmee een bestaande map kan worden gebruikt. De stap waarin het bestand wordt geschreven, wordt pas uitgevoerd nadat een nieuwe map is gemaakt. Zo overschrijft deze installatie geen eerder voorbeeld. In de shelldocumentatie van Apple wordt uitgelegd hoe je met printf en uitvoeromleiding tekstbestanden maakt. Shellinvoer en -uitvoer

Houd deze oefening in die tijdelijke map. Open in Finder je bureaublad en zoek Line Insert Demo; nadat je de opdracht hebt gemaakt, selecteer je het bestand notes.txt daarin.

Een Finder-opdracht maken met het juiste invoertype

Maak in Opdrachten een opdracht met de naam Insert Birch Before Line 3. Apple beschrijft hoe je een opdracht maakt met de knop ‘Voeg toe’ in de knoppenbalk, er een naam aan geeft en acties toevoegt vanuit de navigatiekolom. Een aangepaste opdracht maken op de Mac

Configureer deze als volgt:

  1. Open Details van de opdracht en schakel Gebruik als snelle taak in, met Finder geselecteerd.
  2. Wijzig in de invoerkop van de opdracht de geaccepteerde inhoud in Bestanden en schakel de andere typen uit.
  3. Voeg de actie Voer shellscript uit toe.
  4. Stel Shell in op /bin/sh, Invoer op Invoer opdracht en Geef invoer door op als argumenten.
  5. Vervang het voorbeeldscript van de actie door het volledige programma in het volgende gedeelte.

Apple beschrijft hoe je Finder-opdrachten inschakelt en de geaccepteerde invoertypen beperkt. Het type Bestanden omvat veel soorten documenten. Deze instelling maakt dus bestanden beschikbaar voor de opdracht, maar controleert niet of ze de juiste tekstopmaak hebben. Het script voert aanvullende controles uit. Een opdracht uitvoeren terwijl je op de Mac werkt, De invoer voor een opdracht beperken, Invoertypen begrijpen

De invoerketen is belangrijk: Finder geeft een bestand door aan Opdrachten, waarna de shellactie het pad als argument doorgeeft. In het script is dit beschikbaar als $1. Plaats geen actie die tekst leest vóór de shellactie: dit programma heeft het bestandspad nodig om het bestaande bestand te kunnen lezen en een naam voor een uitvoerbestand in dezelfde map te kunnen kiezen.

Apple bevestigt dat je met Opdrachten voor de Mac shellscripts rechtstreeks in de editor kunt uitvoeren. Als scripts uitvoeren is uitgeschakeld, kies je Opdrachten > Instellingen, open je Geavanceerd en schakel je Sta uitvoeren van scripts toe in. Maak kennis met Opdrachten voor macOS, Geavanceerde instellingen voor Opdrachten

De regel invoegen en een apart resultaat maken

Plak dit volledige programma in Voer shellscript uit. Het programma vereist één bestaand normaal bestand, voegt Birch in vóór regel 3 en schrijft een bestand in dezelfde map met .inserted.txt achter het bronpad.

#!/bin/sh
set -eu

fail() {
    printf '%s\n' "$1" >&2
    exit 1
}

[ "$#" -eq 1 ] || fail 'Select exactly one example text file.'
file=$1
line=3

case "$file" in
    /*) ;;
    *) fail 'The input must be an absolute file path.' ;;
esac

[ -f "$file" ] || fail 'The input file does not exist or is not a regular file.'
[ ! -L "$file" ] || fail 'Select the example file itself, not a symbolic link.'
[ -r "$file" ] || fail 'The input file cannot be read.'

count=$(/usr/bin/sed -n '$=' "$file") || fail 'Could not count the input lines.'
[ -n "$count" ] || fail 'The input file is empty.'
[ "$line" -le "$count" ] || fail 'The insertion line is beyond the end of the file.'

output="${file}.inserted.txt"
if [ -e "$output" ] || [ -L "$output" ]; then
    fail 'The output name already exists. Inspect or rename that result first.'
fi

if (
    set -C
    /usr/bin/sed "${line}i\\
Birch
" "$file" > "$output"
); then
    printf 'Created edited copy: %s\n' "$output"
else
    fail 'Could not finish the edited copy. Inspect any partial output before retrying.'
fi

De fysieke regeleinden binnen de expressie sed zijn bewust aangebracht. Laat de backslash na i staan, behoud de newline erna en zet de in te voegen tekst op een eigen regel. De opdrachtstructuur volgt de door Apple gedistribueerde handleiding en is niet afhankelijk van een compacte schrijfwijze voor invoegen die is overgenomen uit een andere implementatie van sed. Handleiding voor sed: opdrachten en invoegtekst

De omliggende controles bepalen hoe de workflow zich gedraagt. Als je tekst vóór een genummerde regel wilt invoegen, moet die regel bestaan. Daarom weigert dit programma een leeg bestand en een doelregel die na de laatste regel valt. Het weigert ook een bestaande naam voor het uitvoerbestand; de noclobber-modus van de shell biedt een extra controle wanneer het uitvoerbestand wordt geopend.

Het script leest het origineel en schrijft een apart bestand. Als het schrijven mislukt, blijft het origineel beschikbaar, maar kan er wel een onvolledig uitvoerbestand achterblijven. Beschouw een foutmelding als een bewerking die niet is voltooid en controleer dat uitvoerbestand voordat je het verwijdert of het opnieuw probeert. Voer steeds maar één exemplaar tegelijk uit en laat het bronbestand tijdens de bewerking ongewijzigd.

De uitvoer van de actie is een tekstbericht met een pad, geen bestandsobject van Opdrachten. Het bewerkte bestand wordt aangemaakt met de omleiding in het script. Als je daarna Bewaar bestand toevoegt, wordt de uitvoer van de actie bewaard in plaats van de bedoelde regelinvoeging uitgevoerd. Apple beschrijft Bewaar bestand als een deelactie voor bestandsbeheer; de documentatie beschrijft deze actie niet als een editor voor genummerde regels. Over deelacties in Opdrachten op de Mac

Uitvoeren, het resultaat controleren en de oorspronkelijke bestandsnaam behouden

Klik in Finder met de Control-toets ingedrukt op het tijdelijke bestand notes.txt en kies Snelle taken en vervolgens Insert Birch Before Line 3. Apple beschrijft deze manier om een opdracht te starten. Ontbreekt de opdracht? Controleer dan of Finder is ingeschakeld bij de details en of Bestanden is opgenomen in de geaccepteerde invoer. Een opdracht uitvoeren terwijl je op de Mac werkt

Na een geslaagde uitvoering bevat de demomap zowel notes.txt als notes.txt.inserted.txt. Open het laatste bestand en controleer of de inhoud precies als volgt is:

Cedar
Maple
Birch
Willow

Je kunt de uitvoer ook vanuit Terminal controleren met deze volledige opdracht:

/bin/cat "$HOME/Desktop/Line Insert Demo/notes.txt.inserted.txt"

Om de bewerkte inhoud op het oorspronkelijke pad te zetten, sluit je de voorbeeldbestanden en voer je deze twee naamswijzigingen uit in Finder. Controleer eerst dat notes.original.txt nog niet bestaat. Kies een andere ongebruikte back-upnaam als dat wel zo is.

  1. Selecteer notes.txt, druk op Return, wijzig de naam in notes.original.txt en druk opnieuw op Return.
  2. Selecteer notes.txt.inserted.txt, druk op Return, wijzig de naam in notes.txt en druk opnieuw op Return.
  3. Open het bestand met de nieuwe naam notes.txt en controleer de vier regels.

Apple beschrijft hoe je een onderdeel selecteert en op Return drukt om de naam te wijzigen. Behoud in beide namen de uiteindelijke .txt-extensie. Als Finder meldt dat er al een onderdeel met die naam bestaat, stop je en controleer je dat onderdeel voordat je een ongebruikte naam kiest. Bestanden, mappen en schijven hernoemen op de Mac

Hiermee staat de bewerkte inhoud onder notes.txt en de oorspronkelijke inhoud onder notes.original.txt. Hiermee wordt vervangen welk bestand het oorspronkelijke pad bezet; de identiteit van het oorspronkelijke bestand blijft niet behouden en er is geen garantie dat Finder-tags, uitgebreide kenmerken of andere metadata worden overgenomen.

De invoeging aanpassen zonder de betekenis te veranderen

Wijzig voor een ander tijdelijk bestand line=3 in het nummer van een bestaande regel en vervang Birch door een eenvoudige tekstregel. Laat de getoonde invoersyntaxis intact. De voorbeeldtekst bevat bewust geen aanhalingstekens, dollartekens, backticks of backslashes; voor willekeurige tekst is extra quoting voor de shell en sed nodig.

Gebruik deze tabel voordat je het script aanpast:

Gewenste wijziging Wat je moet doen
Tekst vóór de eerste regel zetten Stel line=1 in op een niet-leeg voorbeeldbestand.
Tekst vóór een andere bestaande regel zetten Stel line in op het positieve regelnummer van die regel.
Tekst na de laatste regel toevoegen Gebruik een aparte toevoegbewerking; dit programma weigert een niet-bestaande doelregel.
Tekst invoegen in een leeg bestand Maak de eerste inhoud apart aan; er bestaat geen bestaande regel om op te geven.
Dezelfde opdracht twee keer uitvoeren Controleer eerst de eerdere uitvoer. Nadat je het origineel hebt vervangen, voegt een volgende uitvoering nog een kopie van de tekst in.

Voor deze taak op de desktop zijn de nuttige controlepunten het geselecteerde bestand, de invoegpositie, het voltooide resultaat en de uiteindelijke bestandsnaam. Zodra het voorbeeld van vier regels klopt, kun je dezelfde stappen gebruiken om een andere eenvoudige invoeging te testen en de oorspronkelijke tekst beschikbaar te houden.

Bronnen