Reputation: 471
I have a file named file.txt
which contains data in the following format:
John
file
Abr
John
Tutu
I can read the file line by line using the following way:
#!/bin/sh
while read fl
do
echo $fl
done < file.txt
But I want to print a line with its following lines
I tried the script:
#!/bin/sh
prev=""
while read fl; do
prev="$fl"
done < file.txt
But this script does the things with consecutive lines only. please suggest some better solution.
Expected output:
John file
John Abr
John John
John Tutu
then
file Abr
file John
file Tutu
then
Abr John
Abr Tutu
then
John Tutu
Upvotes: 2
Views: 118
Reputation: 203532
If the output order doesn't matter then:
$ cat tst.awk
BEGIN { OFS="\t" }
NR > 1 {
for (i=1; i<NR; i++) {
print words[i], $0
}
}
{ words[NR]=$0 }
$ awk -f tst.awk file
John file
John Abr
file Abr
John John
file John
Abr John
John Tutu
file Tutu
Abr Tutu
John Tutu
or if it does:
$ cat tst.awk
BEGIN { OFS="\t" }
NR > 1 {
for (i=1; i<NR; i++) {
print i, NR, words[i], $0
}
}
{ words[NR]=$0 }
$ awk -f tst.awk file | sort -k1,2n | cut -f3-
John file
John Abr
John John
John Tutu
file Abr
file John
file Tutu
Abr John
Abr Tutu
John Tutu
Upvotes: 0
Reputation: 10314
Using a recursive bash function
#!/bin/bash
list_compare() {
test ${#@} -lt 2 && return # terminating condition
local name="$1"
shift
for e in "${@}"; do
echo -n "$name $e"
test "$name" == "$e" && echo ' <- match' || echo
done
echo
list_compare "$@" # call again with what's left after shift
}
list_compare $(<file.txt)
Output
John file John Abr John John <- match John Tutu file Abr file John file Tutu Abr John Abr Tutu John Tutu
Upvotes: 0
Reputation: 133518
1st solution: With single pass Input_file please try following awk
code.
awk '
{
arr[FNR]=$0
}
END{
for(i=1;i<=FNR;i++){
for(j=(i+1);j<=FNR;j++){
print arr[i],arr[j]
}
}
}
' Input_file
Explanation: Adding detailed explanation for above.
awk ' ##Starting awk program from here.
{
arr[FNR]=$0 ##Creating arr with index of FNR and value of $0.
}
END{ ##Starting END block of this program from here.
for(i=1;i<=FNR;i++){ ##Running 1st loop till FNR value.
for(j=(i+1);j<=FNR;j++){ ##Running 2nd loop till FNR value, with starting value i+1 here.
print arr[i],arr[j] ##Printing array with index of i and j here.
}
}
}
' Input_file ##Mentioning Input_file name here.
2nd solution: With your shown samples, please try following code.
awk '
FNR==NR{
arr[++count]=$0
next
}
{
for(i=(FNR+1);i<=count;i++){
print $0,arr[i]
}
}
' Input_file Input_file
Explanation: Adding detailed explanation for above.
awk ' ##Starting awk program from here.
FNR==NR{ ##Checking condition FNR==NR here.
arr[++count]=$0 ##Creating array with index of count with increasing value of 1 and its value is current line.
next ##next will skip all further statements from here.
}
{
for(i=(FNR+1);i<=count;i++){ ##Running loop from next line to count here.
print $0,arr[i] ##Printing current line and array element here.
}
}
' Input_file Input_file ##Mentioning Input_file name here.
Upvotes: 2
Reputation:
awk's empty RS might suit your data:
awk -F '\n' -v RS= '{for (i=1;i<NF;++i) for (j=i+1;j<=NF;++j) print $i,$j}' file
Upvotes: 3