# bash script

## commanderhammiltion

hallo leute, ich hoffe ich bin nicht ganz off topic.

folgendes problem:

In einem Verzeichniss liegen etwa, 30.000 Datein. Alle diese Datein sind textdatein, in einigen dieser Textdatein steht eine bestimmte Zeichenkette.

Ich möchte nun ein Script schreiben was alle Datein in diesem Verzeichniss durchsucht und wenn eine entsprechende datei gefunden wurde 

diese in ein anderes verzeichniss kopiert.

leider stehe ich gerade total auf dem schlauch und wäre um eine schnelle hilfe sehr dankbar

----------

## firefly

ich mach geb erstmal ein paar hinweise  :Smile: 

- grep bzw egrep

- schleife (z.b. for)

----------

## schachti

```
grep -r -l SUCHBEGRIFF QUELLVERZEICHNIS | xargs -i cp {} ZIELVERZEICHNIS
```

sollte das tun.

----------

## Knieper

Oder:

```

#!/bin/sh

for f in `grep "bla" * | cut -f1 -d:`

do

        cp $f pfad

done

```

wenn die Parameterzahl etwas zu hoch ist.

----------

## firefly

 *Knieper wrote:*   

> Oder:
> 
> ```
> 
> #!/bin/sh
> ...

 

moep das geht auch einfacher nur mit grep  :Wink: 

for i in $(grep -l test ./*); do echo $i; done

----------

## schachti

Das geht aber schief, wenn Dateinamen mit Leerzeichen vorkommen, oder?

----------

## firefly

 *schachti wrote:*   

> Das geht aber schief, wenn Dateinamen mit Leerzeichen vorkommen, oder?

 

hmm stimmt.

dann machen wir es halt so:

```
OLDIFS=$IFS     # sicherheitshalber den alten inhalt von IFS speichern

IFS=$"\n"                                #<------ IFS auf \n (neue zeile umstellen), da grep eine liste liefert deren einzelne Elemente mit dem neue zeilen zeichen getrennt sind 

for i in $(grep -l hallo ./*)

do

    echo $i

done

IFS=$OLDIFS           # alten IFS wert wieder zurückschreiben
```

dann klappt es auch mit Dateien die Leerzeichen im namen haben.

IFS (Internal Field Separator) wird z.b. von der for-schleife verwendet um einen stream, hier liste von dateien, in tokens zu zerlegen

----------

## commanderhammiltion

hallo, wenn ich folgendes eingebe:

grep -r -l MSH|^~ . | xargs -i cp {} ./hl7

der suchstring ist MSH|^~

wenn ich das eingebe kommt

-bash: ^~: command not found

----------

## schachti

Klappt es, wenn Du den Suchstring in Anführungszeichen einschließt? Du mußt dabei noch beachten, dass ^ im Rahmen von regulären Ausdrücken eine besondere Bedeutung hat.

----------

## Knieper

 *firefly wrote:*   

> moep das geht auch einfacher nur mit grep 

 

Stimmt, aber bei -l haette ich nachsehen muessen, bei cut nicht.  :Wink: 

 *schachti wrote:*   

> Das geht aber schief, wenn Dateinamen mit Leerzeichen vorkommen, oder?

 

Ja, aber wer macht das schon. Man kann ja auch (das langsamere) find nehmen und hat die Probleme dann nicht mehr.

Es kann sich aber noch ein Problem ergeben:

 *commanderhammiltion wrote:*   

> grep -r -l MSH|^~ . | xargs -i cp {} ./hl7

 

Wenn er rekursiv grep()t und in ein Unterverzeichnis kopiert, geht grep irgendwann dort hinein und durchsucht die schon kopierten Dateien. Waere ua. auch mit find zu loesen (oder einer genaueren Angabe als '.').

----------

