Python 2.7 - optimised way to replace only a part of entire command line - linux

I have a text file say 1.txt from where I am fetching some keywords like "sent", "inbox", "outbox" etc. for it to be replaced in a command line.
Below is how the command line looks:
curl -H "pqr: thisisalsolink" -X PUT "https://example.com/artifactory/xyz/mainlist/oldtext.txt" -T newtext.txt
I am trying to replace the "mainlist" with the data i fetched from 1.txt file, e.g.
curl -H "pqr: thisisalsolink" -X PUT "https://example.com/artifactory/xyz/sent/oldtext.txt" -T newtext.txt
curl -H "pqr: thisisalsolink" -X PUT "https://example.com/artifactory/xyz/inbox/oldtext.txt" -T newtext.txt
I have tried by adding this by creating two strings and concatenating it but looks like I am going wrong.
ltppath=r"/home/Desktop/1.txt"
with open((ltppath),'r') as fh:
ls=fh.readlines()
for line in ls:
string1="curl -H "pqr: thisisalsolink" -X PUT "https://example.com/artifactory/xyz/"+line.strip()
string2="/oldtext.txt" -T newtext.txt"
conc=string1+string2
cmd=os.system(conc)
Can someone please help me in finding solution for this i am very new to python.

It doesn't make a lot of sense to me to use Python to generate command lines that you then pass back to the shell to execute. You could use a bash script for that, that would be a lot simpler than Python:
while read line; do
curl -H "pqr: thisisalsolink" -X PUT "https://example.com/artifactory/xyz/$line/oldtext.txt" -T newtext.txt
done </home/Desktop/1.txt
If you're doing it with Python, do it with Python. A nice library to do HTTP is called requests (docs).
import requests
upload_headers = {
'pqr': 'thisisalsolink'
}
with open('/home/Desktop/1.txt', 'r') as fh:
for line in fh:
url = 'https://example.com/artifactory/xyz/' + line.strip() + '/oldtext.txt'
with open('/home/Desktop/newtext.txt') as new_txt:
requests.put(url, headers=upload_headers, data=new_txt)

Related

How to add content of file, as part of a terminal command

I have the following command:
curl -X GET "localhost:9200/bank/_search?pretty" -H 'Content-Type: application/json' -d'
{
"query": { "match_all": {} },
"sort": [
{ "account_number": "asc" }
],
"from": 10,
"size": 10
}
'
I'm trying to divide it into two parts, one part will be saved in a file.
so i can run something like this:
curl -X GET "localhost:9200/bank/_search?pretty" file.txt
How can i achieve this?
To send data that comes from a file, rather than a command line argument, use -d#file.txt:
curl -X GET "localhost:9200/bank/_search?pretty" -d#file.txt
From the curl(1) manual page:
If you start the data with the letter #, the rest should be a
file name to read the data from, or - if you want curl to read
the data from stdin. Posting data from a file named 'foobar'
would thus be done with -d, --data #foobar. When -d, --data is
told to read from a file like that, carriage returns and new‐
lines will be stripped out.
For JSON, stripping line breaks like that fortunately doesn't matter.
You can read the file in place
curl -X GET "localhost:9200/bank/_search?pretty" $(cat file.txt)

Linux print file and use it in for example a curl request

This might be a complete noob question, but I would like to know a simple oneliner to solve my problem.
Imagine following: I have 5 files, could be .txt, .sql .anything.
root#DESKTOP:/$ ls
test.sql test1.sql test2.sql test3.sql
Imagine I would like to use for example test.sql in a curl request as part of a json parameter.
root#DESKTOP:/$ cat test.sql |
curl -H "Accept: application/json"
-H "Content-type: application/json"
-X POST -d "{ \"sqlcommand\" :\"??????" }"
http://localhost:9999/api/testsql
How can I put the output of the cat command in this request at the place of the questionmark? $0, $1 etc are not sufficient. I know how to do it with a for loop. And I could write a shell script that takes an input parameter that I could paste in the command. But. I would like to do it in a simple oneliner and moreover I'd like to learn how I can get the output of the previous command when I need to use it combined with other data OR when it is bad practice i'd like to know the best practice.
Thank you in advance!
This should do what you need:
curl -X POST -d "{ \"sqlcommand\" :\"$(cat test.sql)\" }"
$(cmd) substitutes the result of cmd as a string

Curl/sed command not processing inputs correctly

I'm having some trouble with getting this to do what I want it to do.
read -p "URL to read: " U
read -p "Word to fin: " O
read -p "Filename: " F
curl -O $U | sed "s/\<$O\>/\*$O\*/g" > $F.txt
So basically what I want is to use curl to get a .txt file from a url, then sort through it to find the word specified by the user input. Then mark all those words with a * and put them in a file specified by the user.
Almost the exact same code works in Linux, but this doesn't work on my Mac. Anyone got an idea?
Two issues:
-O makes curl store the downloaded file, not output it on stdout.
word boundary metacharacters \< and \> are a GNU extension. On BSD sed, you can use [[:<:]] and [[:>:]] instead.
This should work on OSX:
curl "$U" | sed "s/[[:<:]]$O[[:>:]]/\*$O\*/g" > $F.txt

Get Content-Disposition filename without downloading

I'm currently using
curl -w "%%{filename_effective}" "http://example.com/file.jpg" -L -J -O -s
to print the server-imposed filename from a download address but it downloads the file to the directory. How can I get the filename only without downloading the file?
Do a HEAD request in your batch file:
curl -w "%%{filename_effective}" "http://example.com/file.jpg" -I -X HEAD -L -J -O -s
This way, the requested file itself will not be downloaded, as per RFC2616:
The HEAD method is identical to GET except that the server MUST NOT return a message-body in the response. (...) This method can be used for obtaining metainformation about the entity implied by the request without transferring the entity-body itself.
Note that this will create two files nonetheless, albeit only with the header data curl has received. I understand that your main interest is not downloading (potentially many and/or big) files, so I guess that should be OK.
Edit: On the follow-up question:
Is there really no way to get only and only the content-disposition filename without downloading anything at all?
It doesn't seem possible with curl alone, I'm afraid. The only way to have curl not output a file is the -o NUL (Windows) routine, and if you do that, %{filename_effective} becomes NUL as well.
curl gives an error when trying to combine -J and -I, so the only solution that I found is to parse the header output with grep and sed:
curl "http://example.com/file.jpg" -LIs | grep ^Content-Disposition | sed -r 's/.*"(.*)".*/\1/'

Using multiple layers of quotes in bash

I'm trying to write a bash script, and I'm running into a quoting problem.
The end result I'm after is for my script to call:
lwp-request -U -e -H "Range: bytes=20-30"
My script file looks like:
CLIENT=lwp-request
REQ_HDRS=-U
RSP_HDRS=-e
RANGE="-H "Range: bytes=20-30"" # Obviously can't do nested quotes here
${CLIENT} ${REQ_HDRS} ${RSP_HDRS} ${RANGE}
I know I can't use nested-quotes. But how can I accomplish this?
Normally, you could escape the inner quotes with \:
RANGE="-H \"Range: bytes=20-30\""
But this won't work when running a command – unless you put eval before the whole thing:
RANGE="-H \"Range: bytes=20-30\""
eval $CLIENT $REQ_HDRS $RSP_HDRS $RANGE
However, since you're using bash, not sh, you can put separate arguments in arrays:
RANGE=(-H "Range: bytes=20-30")
$CLIENT $REQ_HDRS $RSP_HDRS "${RANGE[#]}"
This can be extended to:
ARGS=(
-U # Request headers
-e # Response headers
-H "Range: bytes=20-30" # Range
)
$CLIENT "${ARGS[#]}"
try this:
RANGE='\"-H \"Range: bytes=20-30\"\"
you can espape using '' and \"
no_error=''errors=\"0\"'';
You can use the fact that both '' and "" can be used for strings.
So you can do things like this:
x='Say "hi"'
y="What's up?"

Resources