Ich versuche, ein Skript zu erstellen, das jede Zeile einer Datei durchsucht und, wenn eine Zeile an keiner Stelle mit einer Zeile einer anderen Textdatei übereinstimmt, diese Zeile aus der Originaldatei entfernt.
Ein Beispiel für die gewünschte Eingabe und Ausgabe dieses Skripts wäre:
Beispieleingabe: Datei 1 (Gruppendatei),
hello
hi hello
hi
great
interesting
file 2:
this is a hi you see
this is great don't ya think
sometimes hello is a good expansion of its more commonly used shortening hi
interesting how brilliant coding can be just wish i could get the hang of it
Beispiel für Skriptausgabe – Datei 1 geändert in:
hello
hi
great
interesting
Es wird also entfernt hi hello
, da es in der zweiten Datei nicht vorhanden ist.
hier ist das Skript, es scheint soweit zu funktionieren, dass die Variablen erstellt werden.
#take first line from stability.contigs.groups
echo | head -n1 ~/test_folder/stability.contigs.groups > ~/test_folder/ErrorFix.txt
#remove the last 5 character
sed -i -r '$ s/.{5}$//' ~/test_folder/ErrorFix.txt
#find match of the word string in errorfix.txt in stability.trim.contigs.fasta if not found then delete the line containing the string in stability.contigs.groups
STRING=$(cat ~/test_folder/MothurErrorFix.txt)
FILE=~/test_folder/stability.trim.contigs.fasta
if [ ! -z $(grep "$STRING" "$FILE") ]
then
perl -e 's/.*\$VAR\s*\n//' ~/test_folder/stability.contigs.groups
fi
Antwort1
Wenn ja, gnu grep
können Sie Folgendes ausführen:
grep -oFf file1 file2 | sort | uniq | grep -Ff - file1
Entfernen Sie das letzte grep
, wenn die Zeilenreihenfolge in nicht beibehalten werden muss file1
.
Wenn Sie keinen Zugriff auf haben gnu grep
, mit awk
:
awk 'NR==FNR{z[$0]++;next};{for (l in z){if (index($0, l)) y[l]++}}
END{for (i in y) print i}' file1 file2
Antwort2
Wenn Sie haben, verwenden Sie die (akzeptierte) Antwort von don_crissti GNU grep
. Falls nicht (z. B. auf einem Standard-Mac OS X, wo das nicht funktioniert), können Sie diesen Ausschnitt alternativ in einem Bash-Skript speichern, z. B.myconvert.sh
#!/bin/bash
while IFS='' read -r line || [[ -n "$line" ]]; do
if ! grep -Fq "$line" $2
then
sed -i '' "/$(echo $line | sed -e 's/[]\/$*.^|[]/\\&/g')/d" $1
fi
done < "$1"
und rufe es mit den beiden Dateien als Argumente auf
./myconvert.sh file1 file2
Beachten Sie jedoch die sachkundigen Kommentare von don_crissti weiter unten bezüglich der Verwendung von while/read und den offensichtlichen Leistungsnachteilen beim Aufruf von sed
.