How to merge two rows in a same row from a text file in linux shell script
You can use awk to merge lines together:
awk '
/^ +/{ # For lines starting with spaces,
gsub(/^ +/," "); # Replace these multiple spaces with only one
a=a $0; # Store the line into the variable a
next # Continue with the next line
}
{ # For lines not starting with spaces
$3=$3 a; # Append the variable a to the third element
a="" # Clear variable a
}
1 # Print the current line
' b.txt
How to combine two different rows by using awk sed or shell script
Since it is hard to determine which column the string belongs to, I make the following assumption:
- The columns are perfectly aligned and space separated
so the following awk script will assume:
- A line that does not start with a date will be merged into the next line
- The width of the columns will be determined by the column-width of next line
note: if your file is aligned with blanks (a combination of tabs and spaces), we cannot make use of the field separator "\t" to distinguish fields as the number of tabs will depend on the field width.
Here is the tested script:
# If you have a tab-aligned file, replace all tabs by the
# correct sequence of spaces. In this example, we assume a single
# tab is equivalent to 8 spaces. Adopt if needed
{ gsub(/\t/," ",$0) }
# If the line does not start with a combination of numbers and hyphens
# it is a line that needs to be merged into the next line.
# store it and move to the next line
($1 !~ /^[-0-9]+$/) { tomerge=$0; next }
# If we picked up a tomerge line, try to figure out the fields
# by looking into the current line and determining the field widths.
(tomerge != "") {
# extract fields
n=1
for(i=1;i<NF;++i) {
m=index($0,$(i+1))
field[i]=substr(tomerge,n,m-n)
sub(/^[[:blank:]]*/,"",field[i]) # remove leading blanks
sub(/[[:blank:]]*$/,"",field[i]) # remove trailing blanks
n=m
}
field[NF]=substr(tomerge,n)
# perform merging
for(i=1;i<=NF;++i) $i= field[i] $i
# reset the tomerge value
tomerge=""
}
# print the line
{ $1=$1;print $0 }
which outputs:
$ awk -f script.awk file.txt
02-10-2018 11:50 linux-is-a-opensource user file
02-10-2018 11:46 linux-userfile user file1
02-10-2018 11:40 linux-userfile user-1user file2
02-10-2018 11:30 linux-linux-userfile user-2user file3
If you want it aligned, you can pass it to column -t
as
$ awk -f script.awk file.txt | column -t
merge lines of a txt file using shell script
Here's one way using GNU sed
:
sed ':a; N; $!ba; s/\\\n//g; s/\\$//' file
Another way using awk
, may give you better performance:
awk '{ sub ("\\\\$", ""); printf "%s", $0 } END { print "" }' file
Results:
aaaaabbbbbccccc
Explanation:
The awk
solution removes the trailing backslash (via substitution) and printf's each line (without a newline character). END
(which is executed at the end of the script) then prints a newline character. This is superior to the sed
solution, which creates a label called a
and appends the next line of input into the pattern space. $!ba
means 'if not at the last line of input, branch to label a
'. The first substitution then removes each backslash and newline character from the pattern space. The second substitution removes the last, trailing backslash. This solution should be fast for small files, but probably won't be any faster than the awk
for the same file. Although ... it was faster to write.
How to merge two files line by line in Bash
You can use paste
:
paste file1.txt file2.txt > fileresults.txt
How to merge every two lines into one from the command line?
awk:
awk 'NR%2{printf "%s ",$0;next;}1' yourFile
note, there is an empty line at the end of output.
sed:
sed 'N;s/\n/ /' yourFile
How to concatenate multiple lines of output to one line?
Use tr '\n' ' '
to translate all newline characters to spaces:
$ grep pattern file | tr '\n' ' '
Note: grep
reads files, cat
concatenates files. Don't cat file | grep
!
Edit:
tr
can only handle single character translations. You could use awk
to change the output record separator like:
$ grep pattern file | awk '{print}' ORS='" '
This would transform:
one
two
three
to:
one" two" three"
Faster way to merge multiple files with unequal number of rows by column in bash
You could put all in one awk
script:
awk -F'|' '{if (NR==FNR) a[$1]=$2; else print $1 "|" a[$1] " " $2}' a.txt b.txt
001|johan chu
001|johan stewart
002|mike lewis
002|mike jordan
003|adam lambert
003|adam johnson
003|adam smith
003|adam long
Bash to merge 2 consecutive lines in a file
Using sed
:
sed '$!N;s/\n/,/' filename
Using paste
:
paste -d, - - < filename
paste
would leave a trailing ,
in case the input has an odd number of lines.
How to merge two files consistently line by line
You can use paste
to format the files side by side:
$ paste -d" " file1.txt file2.txt
/etc/port1-192.9.200.1-255.555.255.0 /etc/port1-192.90.2.1-255.555.0.0
/etc/port2-192.9.200.1-255.555.255.0 /etc/port2-192.90.2.1-255.555.0.0
/etc/port3-192.9.200.1-255.555.255.0 /etc/port3-192.90.2.1-255.555.0.0
/etc/port4-192.9.200.1-255.555.255.0 /etc/port4-192.90.2.1-255.555.0.0
/etc/port5-192.9.200.1-255.555.255.0 /etc/port5-192.90.2.1-255.555.0.0
E.g.:
$ paste -d" " file1.txt file2.txt | while read from to; do echo mv "${from}" "${to}"; done
mv /etc/port1-192.9.200.1-255.555.255.0 /etc/port1-192.90.2.1-255.555.0.0
mv /etc/port2-192.9.200.1-255.555.255.0 /etc/port2-192.90.2.1-255.555.0.0
mv /etc/port3-192.9.200.1-255.555.255.0 /etc/port3-192.90.2.1-255.555.0.0
mv /etc/port4-192.9.200.1-255.555.255.0 /etc/port4-192.90.2.1-255.555.0.0
mv /etc/port5-192.9.200.1-255.555.255.0 /etc/port5-192.90.2.1-255.555.0.0
Of course you would want to throw in some safety checks ([ -f "${from}" ]
, ...).
Disclaimer: Works only if there are no spaces in your filenames.
Related Topics
How to Start/Restart/Stop Apache Server on Linux as Non-Root User
Knowing If a Remote Port Forward Was Successful
Differentiate Between Exit and Session Timeout
Rsync, 'Uid/Gid Impossible to Set' Cases Cause Future Hard Link Failure, How to Fix
Executable Object Files and Virtual Memory
How to Configure Acpi *.Asl for a Virtual Mdio-Gpio Device Connected to a I2C Gpio Expander
How to Add Output "Non_Assigned" When There Is No Match in Grep
Command Substitution in Bash VS Function Calling
Requirement for Transport Stream Streaming Server
No Console Output Available on Linux When Executing Grails/Groovy
Use Bash Variable Within Slurm Sbatch Script
Measuring Stack Usage for Linux Multi-Threaded App
Sed Find and Replace Between Two Tags with Multi Line
Pthread Condition Variables on Linux, Odd Behaviour
How to Increase Openfabrics Memory Limit for Torque Jobs
Sort Command in Not Working Properly in Unix for Sorting a CSV File