LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (https://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   How to move certain line to the first line (https://www.linuxquestions.org/questions/linux-newbie-8/how-to-move-certain-line-to-the-first-line-4175562249/)

Mike_Brown 12-24-2015 12:49 AM

How to move certain line to the first line
 
I have a data file which contains a line of characters like
Code:

5 0.0275 10 0.2 0 0.2255 0.3105 0.375 0.39 0.231 0.361 0.38 0.2095
5 0.05 10 0.2 0 0.352 0.637 0.7045 0.7095 0.36 0.702 0.7135 0.404
1 0.02 10 0.2 0 0.0845 0.1265 0.0805 0.0865 0.0865 0.126 0.0815 0.0735
4 0.04 10 0.2 0 0.2705 0.4465 0.4945 0.503 0.284 0.517 0.503 0.214
"model" "h" "K" "pcau" "nprot" "CCA" "single_TOW" "MTOW" "AWRR" "CCAc" "single_TOWc" "MTOWc" "AWRRc"
2 0.03 10 0.2 0 0.165 0.2285 0.22 0.221 0.181 0.261 0.229 0.153
2 0.05 10 0.2 0 0.237 0.437 0.288 0.344 0.2425 0.5045 0.2785 0.2025
2 0.02 10 0.2 0 0.1245 0.1605 0.144 0.1365 0.1225 0.184 0.148 0.1025
4 0.02 10 0.2 0 0.1665 0.1945 0.2185 0.202 0.1705 0.217 0.221 0.12
1 0.08 10 0.2 0 0.215 0.2835 0.2215 0.171 0.2265 0.3235 0.233 0.1465
4 0.03 10 0.2 0 0.2185 0.3405 0.3595 0.351 0.2305 0.409 0.363 0.164
5 0.035 10 0.2 0 0.241 0.421 0.439 0.5165 0.245 0.484 0.449 0.275
6 0.03 10 0.2 0 0.13 0.3395 0.223 0.283 0.144 0.3865 0.2325 0.167
6 0.02 10 0.2 0 0.1025 0.2095 0.155 0.1675 0.1035 0.23 0.1595 0.102
6 0.04 10 0.2 0 0.1805 0.4655 0.324 0.3925 0.189 0.5385 0.332 0.17
5 0.02 10 0.2 0 0.1425 0.2235 0.259 0.249 0.162 0.261 0.257 0.1475
4 0.05 10 0.2 0 0.32 0.568 0.6035 0.617 0.3405 0.64 0.62 0.2765
1 0.04 10 0.2 0 0.1305 0.1585 0.12 0.1135 0.135 0.168 0.1255 0.113
6 0.01 10 0.2 0 0.072 0.094 0.0905 0.083 0.067 0.1115 0.0915 0.0645
3 0.07 10 0.2 0 0.4225 0.3655 0.3985 0.368 0.4275 0.4195 0.4 0.4135
3 0.08 10 0.2 0 0.4355 0.422 0.412 0.399 0.4455 0.464 0.4085 0.4095
2 0.06 10 0.2 0 0.285 0.537 0.3565 0.437 0.294 0.571 0.3575 0.2885
4 0.01 10 0.2 0 0.101 0.097 0.115 0.1045 0.1085 0.1155 0.115 0.0665
1 0.1 10 0.2 0 0.279 0.343 0.2375 0.227 0.289 0.367 0.2565 0.183
1 0.06 10 0.2 0 0.1945 0.2045 0.1485 0.154 0.2035 0.2365 0.1535 0.1315
3 0.06 10 0.2 0 0.3455 0.3225 0.311 0.326 0.3565 0.3535 0.309 0.362
5 0.0425 10 0.2 0 0.3145 0.5365 0.596 0.625 0.3185 0.6095 0.614 0.338
2 0.04 10 0.2 0 0.2005 0.3485 0.2585 0.2865 0.208 0.3875 0.2655 0.196
3 0.05 10 0.2 0 0.2965 0.2495 0.266 0.2655 0.303 0.2865 0.2695 0.2865

Everytime, the number of line which contains characters is not always same. Is there a way to move the line
Code:

"model" "h" "K" "pcau" "nprot" "CCA" "single_TOW" "MTOW" "AWRR" "CCAc" "single_TOWc" "MTOWc" "AWRRc"
to first line?
Suppose I have a batch of these files named as ***.txt. How can I do it at one time?

syg00 12-24-2015 02:43 AM

Simplest would be to just pull that line out with say sed or grep, then pull all the lines *except* that. Redirect all the stdout to a new file. Rename both.
For the list just use bash loop - for i in *.txt ; ...

This causes all the lines before the header to be read twice, but they should still be in page cache, so wouldn't cause any extra physical I/O. Edit: only true if you take steps to quit reading the file after findng the header - else the entire file gets read twice. I use sed to do this.

KISS.

grail 12-24-2015 02:45 AM

I would probably use awk for the moving of the line, but my first question would be, what creates the data? Is it not possible to get the data correct the first time around??

Mike_Brown 12-24-2015 10:32 AM

Quote:

Originally Posted by grail (Post 5468344)
I would probably use awk for the moving of the line, but my first question would be, what creates the data? Is it not possible to get the data correct the first time around??

I am using campus computers to running program, each of computers will write a data line to the above data file. And One computer will write both of the header and the data line to file to let me known what each column represents. Since each computer's speed is different. So the header line in different line number. I cannot control the computer (which will write both of the header and the data line) to finish program first.

grail 12-24-2015 11:25 AM

Fair enough :) So have a look at awk to solve your problem. You can store the lines until the header in an array and then once you find the header, print it and all stored in the array
and just print the rest of the lines after that. You will of course need to redirect this into a new file.

http://www.gnu.org/software/gawk/man...ode/index.html

jpollard 12-24-2015 11:26 AM

I would suggest creating the header first, then have the rest of the systems append to the file without the header...

Aia 12-24-2015 12:08 PM

Maybe something simple as this:
Code:

#!/bin/bash

for i
do
    sed -n '/^[^0-9]/p' "${i}" > "${i}.tmp"
    sed -n '/^[0-9]/p' "${i}"  >> "${i}.tmp"
    #if [ -s "${i}.tmp" ]; then
    #    mv -v "${i}.tmp" "${i}"
    #fi
done

Remove the #s if you are happy with the result.
Run as
Code:

shifter.sh *.txt

rknichols 12-24-2015 01:57 PM

In the spirit of "sed is Turing complete -- it can do anything," how about something as obscure as this:
Code:

$ cat >/tmp/movelabel.sed
/"/{p;x;s/^\n//p;b}
${x;s/"/&/;x;t copy;H;x;s/^\n//p;b}
{x;s/"/&/;x;t copy;H;b;: copy;p;b}
$ sed -i -n -f /tmp/movelabel.sed *.txt

I suggest trying that on just one file and without the "-i" option to see what it does. As written, it uses the presence of a double quote mark to identify the line with the labels. You can substitute whatever string you like for that.

That second line of the script might need a little explanation. It handles the case where no label line is found in the file and just regurgitates the whole file as read if that is the case. Without that line it would discard all the data and leave just an empty file.


All times are GMT -5. The time now is 06:03 PM.