简体   繁体   中英

bash how to print for loop output into one line?

I wish if someone can help me with this,

how can I print the output of for loop into single line?

for i in `cat file.csv`
do
echo $i 
done

what I'm trying to achieve here is to get a list of numbers from file.csv to generate a mysql bulk delete statement.

delete FROM Recordtable WHERE DataID IN ('93041', '93031' ...etc);

and the goal here is to load every 1000 records into one single delete statement

Your help is highly appreciated

If you want the loop, you can use

for i in ($<file.csv)
do
  echo -n "$i "
done

The -n option to echo suppresses the newline.


You can print the entire file in a single line with echo $(<file.csv) .

But this may suit your needs better:

awk '{ printf $0 " " } NR%1000 == 0 { print "" }' file

This will print each line followed by a space. It will print a newline whenever the line number is divisible by 1000; that is, after every 1000th line.


Added: To print each line within parentheses, you can use

awk '{ printf $0 " " } NR%1000 == 0 { print "" }' file | sed 's/.*/(&)/'

The sed command searches for any characters ( .* ) and replaces them with an open-paren, the characters it found (that is, the entire line), and a close-paren.

It seems file.csv contains DataID in a single column. If thats true, you can generate the query like this,

echo delete FROM Recordtable WHERE DataID IN \(0$(cat file.csv | tr -cs '[:digit:]' ',')0\)\;

As the file contains only integers (DataID seems int) so there is no need to enclose it by single quote.

$ cat data
123
241114
43243
35745
656
346   456


$echo delete FROM Recordtable WHERE DataID IN \(0$(cat data | tr -cs '[:digit:]' ',')0\)\;
delete FROM Recordtable WHERE DataID IN (0,123,241114,43243,35745,656,346,456,0);

Here 0 deals with leading and trailing , s.

You can do :

echo $(cat file.csv)

or

cat file.csv | xargs

or finally :

$ cat /tmp/l.csv
1;2;3;4;5;6
7;8;9;10;11
$ echo $(< /tmp/l.csv)
1;2;3;4;5;6 7;8;9;10;11
$ echo $(cat /tmp/l.csv) | perl -pe 's@(;|\n)@,@g'
1,2,3,4,5,6,7,8,9,10,11,
$ 
BULK_DELETE_SQL=/tmp/bulkdelete.sql
rm -f ${BULK_DELETE_SQL}
COMMIT_COUNT=0
COMMIT_LIMIT=1000
NUMLIST=""
COMMA=""
for NUM in `cat file.csv` 
do
    NUMLIST="${NUMLIST}${COMMA}${NUM}"
    COMMA=","
    (( COMMIT_COUNT++ ))
    if [ ${COMMIT_COUNT} -eq ${COMMIT_LIMIT} ]
    then
        SQLSTMT="delete FROM Recordtable WHERE DataID IN (${NUMLIST});"
        echo ${SQLSTMT} >> ${BULK_DELETE_SQL}
        NUMLIST=""
        COMMA=""
        COMMIT_COUNT=0
    fi
done
if [ ${COMMIT_COUNT} -gt 0 ]
then
    SQLSTMT="delete FROM Recordtable WHERE DataID IN (${NUMLIST});"
    echo ${SQLSTMT} >> ${BULK_DELETE_SQL}
fi
mysql -u... -p... < ${BULK_DELETE_SQL}
rm -f ${BULK_DELETE_SQL}

This will write one SQL script that will create 1000 DataIDs per DELETE Statement.

It will only connect to mysql once and perform all the DELETEs, 1000 DataIDs at a time.

If there are 6247 DataIDs in file.csv, then the last line should have 247 DataIDs

If there are 247 DataIDs in file.csv, then the only line should have 247 DataIDs

Give it a Try !!!

You can use perl.

perl -lne '$a .= $_ }{ print $a' file.csv

-l will remove newlines, and will add a newline to the print . -n will read argument file contents. Be aware that if no added whitespace exists in the file, you may with to add it, eg $a .= " $_" .

I assume you are going to pipe this input somewhere to perform the SQL query. I can't help but think this could be better done with DBI .

从“只因为”学校回答:

tr $'\n' ' ' < file.csv

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM